package com.example.meterialproject.view.behavior.demo1

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.os.Bundle
import android.os.Parcelable
import android.util.AttributeSet
import android.util.Log
import android.view.MotionEvent
import android.view.View
import androidx.appcompat.widget.AppCompatTextView
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.os.bundleOf
import com.example.meterialproject.exts.dp
import com.example.meterialproject.exts.name

/**
 *
 * @ClassName: MoveBehavior
 * @Author: android 超级兵
 * @CreateDate: 4/11/22$ 10:52 AM$
 * TODO
 */
class MoveBehavior<T : View>(val context: Context, attrs: AttributeSet?) :
    CoordinatorLayout.Behavior<T>(context, attrs) {

    companion object {
        private const val TAG = "MoveBehavior"
        const val TEXT_STRING = "string"
        const val TEXT_INT = "int"
        const val TEXT_FLOAT = "float"
        const val TEXT_STRING_LIST = "list"
        const val PARCELABLE = "Parcelable"
    }

    /*
     * 作者:android 超级兵
     * 创建时间: 4/22/22 4:45 PM
     * TODO 当解析完布局,也就是 View#onFinishInflate() 执行完的时候执行
     */
    override fun onAttachedToLayoutParams(params: CoordinatorLayout.LayoutParams) {
        super.onAttachedToLayoutParams(params)
        Log.i(TAG, "toLayoutParam")
    }


    /*
     * 作者:android 超级兵
     * 创建时间: 4/22/22 2:34 PM
     * TODO 设置背景色
     *
     * (如果已经设置了)android:background="" 那么不会覆盖
     *
     * 需要配合 getScrimOpacity() 使用 因为 getScrimOpacity() 默认 = 0f
     */
    override fun getScrimColor(parent: CoordinatorLayout,
                               child: T): Int {
        return Color.YELLOW
    }

    /*
     * 作者:android 超级兵
     * 创建时间: 4/22/22 2:35 PM
     * TODO 设置不透明度
     */
    override fun getScrimOpacity(parent: CoordinatorLayout,
                                 child: T): Float {
        return 0.5f
    }


    /*
     * 作者:android 超级兵
     * 创建时间: 4/22/22 4:20 PM
     * TODO 保存状态 和View / Activity 一样
     *
     * tips: 1. 必须保证View在xml中设置了id (android:id="@+id/XXX")
     *       2. 必须保证view参数中有behavior属性 (app:behavior="www.com.XXX")
     */
    override fun onSaveInstanceState(parent: CoordinatorLayout, child: T): Parcelable {

        return bundleOf(
            TEXT_STRING to "博主带你上高速!",
            TEXT_INT to 1120,
            TEXT_FLOAT to 88.88f,
            TEXT_STRING_LIST to arrayListOf("a", "n", "d", "r", "o", "i", "d"),

            // 重点
            PARCELABLE to super.onSaveInstanceState(parent, child),
        )
    }

    /*
     * 作者:android 超级兵
     * 创建时间: 4/22/22 4:24 PM
     * TODO 恢复参数
     */
    override fun onRestoreInstanceState(parent: CoordinatorLayout, child: T, state: Parcelable) {
        (state as? Bundle)?.apply {
            super.onRestoreInstanceState(parent, child, getParcelable(PARCELABLE) ?: return)

            val string = getString(TEXT_STRING)
            val int = getInt(TEXT_INT)
            val float = getFloat(TEXT_FLOAT)
            val stringArrayList = getStringArrayList(TEXT_STRING_LIST)
            Log.i(
                TAG, "onRestoreInstanceState"
                        + "\tstring:$string"
                        + "\tint:$int"
                        + "\tfloat:$float"
                        + "\tstringArrayList:$stringArrayList"
            )
        }

        // 协程写法
//        GlobalScope.launch {
//            flow {
//                emit(state as Bundle)
//            }.onEach {
//                super.onRestoreInstanceState(parent, child, it.getParcelable(PARCELABLE)!!)
//            }.catch {
//                Log.i(TAG, "onRestoreInstanceState error")
//            }.collectLatest {
//                val string = it.getString(TEXT_STRING)
//                Log.i(
//                    TAG, "onRestoreInstanceState"
//                            + "\t string:$string"
//                )
//            }
//        }
    }

    /*
     * 作者:android 超级兵
     * 创建时间: 4/11/22 11:18 AM
     * TODO Behavior需要依赖的类型
     *  child = AppCompatTextView
     *  dependency = MoveView (依赖的view,如果他响应事件会监听到)
     */
    override fun layoutDependsOn(
        parent: CoordinatorLayout,
        child: T,
        dependency: View
    ): Boolean {
        Log.i(
            TAG, "layoutDependsOn\tchild:${child::class.java.simpleName}" +
                    "\tdependency:${dependency::class.java.simpleName}"
        )
        return child is AppCompatTextView && dependency is MoveView
    }

    /*
     * 作者:android 超级兵
     * 创建时间: 4/11/22 11:08 AM
     * TODO 当被依赖的View状态改变时回调
     */
    @SuppressLint("SetTextI18n")
    override fun onDependentViewChanged(
        parent: CoordinatorLayout,
        child: T,
        dependency: View
    ): Boolean {
        Log.i(
            TAG, "onDependentViewChanged\tchild:${child::class.java.simpleName}" +
                    "\tdependency:${dependency::class.java.simpleName}"
        )
        if (child is AppCompatTextView) {
            child.x = dependency.x
            child.y = dependency.y + 120.dp(context)
            child.text = "x:${child.x}\ny${child.y}"
        }

        return super.onDependentViewChanged(parent, child, dependency)
    }

    /*
     * 作者:android 超级兵
     * 创建时间: 4/11/22 11:08 AM
     * TODO 当被依赖的View状态remove时回调
     */
    override fun onDependentViewRemoved(parent: CoordinatorLayout, child: T, dependency: View) {
        Log.i(
            TAG, "onDependentViewRemoved\tchild:${child.name}" +
                    "\tdependency:${dependency.name}"
        )
        super.onDependentViewRemoved(parent, child, dependency)
    }

    /*
     * 作者:android 超级兵
     * 创建时间: 4/11/22 11:10 AM
     * TODO 嵌套滑动开始时候调用
     */
    override fun onStartNestedScroll(
        coordinatorLayout: CoordinatorLayout,
        child: T,
        directTargetChild: View,
        target: View,
        axes: Int,
        type: Int
    ): Boolean {
        Log.i(
            TAG, "onStartNestedScroll\tchild:${child::class.java.simpleName}" +
                    "\tdirectTargetChild:${directTargetChild::class.java.simpleName}" +
                    "\ttarget:${target::class.java.simpleName}"
        )
        return super.onStartNestedScroll(
            coordinatorLayout,
            child,
            directTargetChild,
            target,
            axes,
            type
        )
    }

    /*
     * 作者:android 超级兵
     * 创建时间: 4/11/22 11:12 AM
     * TODO onStartNestedScroll 返回true后立即回掉
     */
    override fun onNestedScrollAccepted(
        coordinatorLayout: CoordinatorLayout,
        child: T,
        directTargetChild: View,
        target: View,
        axes: Int,
        type: Int
    ) {
        Log.i(
            TAG, "onNestedScrollAccepted\tchild:${child::class.java.simpleName}" +
                    "\tdirectTargetChild:${directTargetChild::class.java.simpleName}" +
                    "\ttarget:${target::class.java.simpleName}\taxes:$axes\ttype:$type"
        )
        super.onNestedScrollAccepted(
            coordinatorLayout,
            child,
            directTargetChild,
            target,
            axes,
            type
        )
    }

    override fun onNestedPreScroll(
        coordinatorLayout: CoordinatorLayout,
        child: T,
        target: View,
        dx: Int,
        dy: Int,
        consumed: IntArray,
        type: Int
    ) {
        Log.i(
            TAG, "onNestedPreScroll\tchild:${child::class.java.simpleName}" +
                    "\ttarget:${target::class.java.simpleName}\tdx:$dx\tdy:$dy\tconsumed:${
                        printInts(
                            consumed
                        )
                    }\ttype:$type"
        )
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
    }

    override fun onTouchEvent(parent: CoordinatorLayout, child: T, ev: MotionEvent): Boolean {
        Log.i("szjBehavior Move", "onTouchEvent")
        return super.onTouchEvent(parent, child, ev)
    }

    override fun onInterceptTouchEvent(
        parent: CoordinatorLayout,
        child: T,
        ev: MotionEvent
    ): Boolean {
        Log.i("szjBehavior Move", "onTouchEvent")
        return super.onInterceptTouchEvent(parent, child, ev)
    }


    // 打印所有元素
    private fun printInts(ints: IntArray) = let {
        ints.mapIndexed { index, value ->
            "$index:$value"
        }.toList()
    }

}